home *** CD-ROM | disk | FTP | other *** search
/ Languguage OS 2 / Languguage OS II Version 10-94 (Knowledge Media)(1994).ISO / gnu / glibc108.zip / glibc108 / sunrpc / xdr_float.c < prev    next >
C/C++ Source or Header  |  1994-05-10  |  7KB  |  268 lines

  1. /* @(#)xdr_float.c    2.1 88/07/29 4.0 RPCSRC */
  2. /*
  3.  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
  4.  * unrestricted use provided that this legend is included on all tape
  5.  * media and as a part of the software program in whole or part.  Users
  6.  * may copy or modify Sun RPC without charge, but are not authorized
  7.  * to license or distribute it to anyone else except as part of a product or
  8.  * program developed by the user.
  9.  * 
  10.  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
  11.  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
  12.  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
  13.  * 
  14.  * Sun RPC is provided with no support and without any obligation on the
  15.  * part of Sun Microsystems, Inc. to assist in its use, correction,
  16.  * modification or enhancement.
  17.  * 
  18.  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
  19.  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
  20.  * OR ANY PART THEREOF.
  21.  * 
  22.  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
  23.  * or profits or other special, indirect and consequential damages, even if
  24.  * Sun has been advised of the possibility of such damages.
  25.  * 
  26.  * Sun Microsystems, Inc.
  27.  * 2550 Garcia Avenue
  28.  * Mountain View, California  94043
  29.  */
  30. #if !defined(lint) && defined(SCCSIDS)
  31. static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro";
  32. #endif
  33.  
  34. /*
  35.  * xdr_float.c, Generic XDR routines impelmentation.
  36.  *
  37.  * Copyright (C) 1984, Sun Microsystems, Inc.
  38.  *
  39.  * These are the "floating point" xdr routines used to (de)serialize
  40.  * most common data items.  See xdr.h for more info on the interface to
  41.  * xdr.
  42.  */
  43.  
  44. #include <stdio.h>
  45.  
  46. #include <rpc/types.h>
  47. #include <rpc/xdr.h>
  48.  
  49. /*
  50.  * NB: Not portable.
  51.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  52.  */
  53.  
  54. #ifdef vax
  55.  
  56. /* What IEEE single precision floating point looks like on a Vax */
  57. struct    ieee_single {
  58.     unsigned int    mantissa: 23;
  59.     unsigned int    exp     : 8;
  60.     unsigned int    sign    : 1;
  61. };
  62.  
  63. /* Vax single precision floating point */
  64. struct    vax_single {
  65.     unsigned int    mantissa1 : 7;
  66.     unsigned int    exp       : 8;
  67.     unsigned int    sign      : 1;
  68.     unsigned int    mantissa2 : 16;
  69. };
  70.  
  71. #define VAX_SNG_BIAS    0x81
  72. #define IEEE_SNG_BIAS    0x7f
  73.  
  74. static struct sgl_limits {
  75.     struct vax_single s;
  76.     struct ieee_single ieee;
  77. } sgl_limits[2] = {
  78.     {{ 0x7f, 0xff, 0x0, 0xffff },    /* Max Vax */
  79.     { 0x0, 0xff, 0x0 }},        /* Max IEEE */
  80.     {{ 0x0, 0x0, 0x0, 0x0 },    /* Min Vax */
  81.     { 0x0, 0x0, 0x0 }}        /* Min IEEE */
  82. };
  83. #endif /* vax */
  84.  
  85. bool_t
  86. xdr_float(xdrs, fp)
  87.     register XDR *xdrs;
  88.     register float *fp;
  89. {
  90. #ifdef vax
  91.     struct ieee_single is;
  92.     struct vax_single vs, *vsp;
  93.     struct sgl_limits *lim;
  94.     int i;
  95. #endif
  96.     switch (xdrs->x_op) {
  97.  
  98.     case XDR_ENCODE:
  99. #ifndef vax
  100.         return (XDR_PUTLONG(xdrs, (long *)fp));
  101. #else
  102.         vs = *((struct vax_single *)fp);
  103.         for (i = 0, lim = sgl_limits;
  104.             i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  105.             i++, lim++) {
  106.             if ((vs.mantissa2 == lim->s.mantissa2) &&
  107.                 (vs.exp == lim->s.exp) &&
  108.                 (vs.mantissa1 == lim->s.mantissa1)) {
  109.                 is = lim->ieee;
  110.                 goto shipit;
  111.             }
  112.         }
  113.         is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS;
  114.         is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2;
  115.     shipit:
  116.         is.sign = vs.sign;
  117.         return (XDR_PUTLONG(xdrs, (long *)&is));
  118. #endif
  119.  
  120.     case XDR_DECODE:
  121. #ifndef vax
  122.         return (XDR_GETLONG(xdrs, (long *)fp));
  123. #else
  124.         vsp = (struct vax_single *)fp;
  125.         if (!XDR_GETLONG(xdrs, (long *)&is))
  126.             return (FALSE);
  127.         for (i = 0, lim = sgl_limits;
  128.             i < sizeof(sgl_limits)/sizeof(struct sgl_limits);
  129.             i++, lim++) {
  130.             if ((is.exp == lim->ieee.exp) &&
  131.                 (is.mantissa == lim->ieee.mantissa)) {
  132.                 *vsp = lim->s;
  133.                 goto doneit;
  134.             }
  135.         }
  136.         vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS;
  137.         vsp->mantissa2 = is.mantissa;
  138.         vsp->mantissa1 = (is.mantissa >> 16);
  139.     doneit:
  140.         vsp->sign = is.sign;
  141.         return (TRUE);
  142. #endif
  143.  
  144.     case XDR_FREE:
  145.         return (TRUE);
  146.     }
  147.     return (FALSE);
  148. }
  149.  
  150. /*
  151.  * This routine works on Suns (Sky / 68000's) and Vaxen.
  152.  */
  153.  
  154. #ifdef vax
  155. /* What IEEE double precision floating point looks like on a Vax */
  156. struct    ieee_double {
  157.     unsigned int    mantissa1 : 20;
  158.     unsigned int    exp       : 11;
  159.     unsigned int    sign      : 1;
  160.     unsigned int    mantissa2 : 32;
  161. };
  162.  
  163. /* Vax double precision floating point */
  164. struct  vax_double {
  165.     unsigned int    mantissa1 : 7;
  166.     unsigned int    exp       : 8;
  167.     unsigned int    sign      : 1;
  168.     unsigned int    mantissa2 : 16;
  169.     unsigned int    mantissa3 : 16;
  170.     unsigned int    mantissa4 : 16;
  171. };
  172.  
  173. #define VAX_DBL_BIAS    0x81
  174. #define IEEE_DBL_BIAS    0x3ff
  175. #define MASK(nbits)    ((1 << nbits) - 1)
  176.  
  177. static struct dbl_limits {
  178.     struct    vax_double d;
  179.     struct    ieee_double ieee;
  180. } dbl_limits[2] = {
  181.     {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff },    /* Max Vax */
  182.     { 0x0, 0x7ff, 0x0, 0x0 }},            /* Max IEEE */
  183.     {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},        /* Min Vax */
  184.     { 0x0, 0x0, 0x0, 0x0 }}                /* Min IEEE */
  185. };
  186.  
  187. #endif /* vax */
  188.  
  189.  
  190. bool_t
  191. xdr_double(xdrs, dp)
  192.     register XDR *xdrs;
  193.     double *dp;
  194. {
  195.     register long *lp;
  196. #ifdef vax
  197.     struct    ieee_double id;
  198.     struct    vax_double vd;
  199.     register struct dbl_limits *lim;
  200.     int i;
  201. #endif
  202.  
  203.     switch (xdrs->x_op) {
  204.  
  205.     case XDR_ENCODE:
  206. #ifndef vax
  207.         lp = (long *)dp;
  208. #else
  209.         vd = *((struct vax_double *)dp);
  210.         for (i = 0, lim = dbl_limits;
  211.             i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  212.             i++, lim++) {
  213.             if ((vd.mantissa4 == lim->d.mantissa4) &&
  214.                 (vd.mantissa3 == lim->d.mantissa3) &&
  215.                 (vd.mantissa2 == lim->d.mantissa2) &&
  216.                 (vd.mantissa1 == lim->d.mantissa1) &&
  217.                 (vd.exp == lim->d.exp)) {
  218.                 id = lim->ieee;
  219.                 goto shipit;
  220.             }
  221.         }
  222.         id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS;
  223.         id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3);
  224.         id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) |
  225.                 (vd.mantissa3 << 13) |
  226.                 ((vd.mantissa4 >> 3) & MASK(13));
  227.     shipit:
  228.         id.sign = vd.sign;
  229.         lp = (long *)&id;
  230. #endif
  231.         return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp));
  232.  
  233.     case XDR_DECODE:
  234. #ifndef vax
  235.         lp = (long *)dp;
  236.         return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp));
  237. #else
  238.         lp = (long *)&id;
  239.         if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp))
  240.             return (FALSE);
  241.         for (i = 0, lim = dbl_limits;
  242.             i < sizeof(dbl_limits)/sizeof(struct dbl_limits);
  243.             i++, lim++) {
  244.             if ((id.mantissa2 == lim->ieee.mantissa2) &&
  245.                 (id.mantissa1 == lim->ieee.mantissa1) &&
  246.                 (id.exp == lim->ieee.exp)) {
  247.                 vd = lim->d;
  248.                 goto doneit;
  249.             }
  250.         }
  251.         vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS;
  252.         vd.mantissa1 = (id.mantissa1 >> 13);
  253.         vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) |
  254.                 (id.mantissa2 >> 29);
  255.         vd.mantissa3 = (id.mantissa2 >> 13);
  256.         vd.mantissa4 = (id.mantissa2 << 3);
  257.     doneit:
  258.         vd.sign = id.sign;
  259.         *dp = *((double *)&vd);
  260.         return (TRUE);
  261. #endif
  262.  
  263.     case XDR_FREE:
  264.         return (TRUE);
  265.     }
  266.     return (FALSE);
  267. }
  268.